package com.atguigu.tingshu.order.strategy.impl;

import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.strategy.SaveOrderStrategy;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

// 微信支付保存订单策略方法
@Service
@Slf4j
public class WeiXinSaveOrderStrategy implements SaveOrderStrategy {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderDerateMapper orderDerateMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public OrderInfoVo saveOrder(OrderInfoVo orderInfoVo) {
        log.info("WeiXinSaveOrderStrategy...方法执行了...");
        String orderNo = UUID.randomUUID().toString().replace("-" , "") ;
        this.saveOrderAndDetailAndOrderDerate(orderInfoVo , orderNo);
        orderInfoVo.setTradeNo(orderNo);
        // 发送超时未支付自动取消订单的延迟消息
        sendDelayMessage(orderNo) ;
        return orderInfoVo;
    }


    //延迟消息
    private void sendDelayMessage(String orderNo) {
        try {
            RBlockingDeque<Object> orderCancelBlockingDeque = redissonClient.getBlockingDeque(KafkaConstant.QUEUE_ORDER_CANCEL);    // 获取阻塞队列
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(orderCancelBlockingDeque);                          // 创建延迟队列
            delayedQueue.offer(orderNo , KafkaConstant.DELAY_TIME , TimeUnit.SECONDS);                                              // 发送延迟消息
            log.info("添加延时队列成功 ，延迟时间：{}，订单id：{}", KafkaConstant.DELAY_TIME, orderNo);
        }catch (Exception e) {
            e.printStackTrace();
            log.error("添加延时队列失败 ，延迟时间：{}，订单id：{}", KafkaConstant.DELAY_TIME, orderNo);
        }

    }


    // 生成订单数据
    private String saveOrderAndDetailAndOrderDerate(OrderInfoVo orderInfoVo, String orderNo) {
        // 获取当前登录用户id
        Long userId = AuthContextHolder.getUserId();

        // 保存订单数据
        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(orderInfoVo, orderInfo);
        orderInfo.setOrderNo(orderNo);
        String orderTitle = orderInfoVo.getOrderDetailVoList().get(0).getItemName();
        orderInfo.setOrderTitle(orderTitle);
        orderInfo.setUserId(userId);
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_UNPAID);
        orderInfoMapper.insert(orderInfo);      //  保存订单

        // 保存订单明细
        if (!CollectionUtils.isEmpty(orderInfoVo.getOrderDetailVoList())) {
            orderInfoVo.getOrderDetailVoList().forEach(orderDetailVo -> {
                OrderDetail orderDetail = new OrderDetail();
                BeanUtils.copyProperties(orderDetailVo, orderDetail);
                orderDetail.setOrderId(orderInfo.getId());
                orderDetailMapper.insert(orderDetail);
            });
        }

        // 保存扣减明细数据
        if (!CollectionUtils.isEmpty(orderInfoVo.getOrderDerateVoList())) {
            orderInfoVo.getOrderDerateVoList().forEach(orderDerateVo -> {
                OrderDerate orderDerate = new OrderDerate();
                BeanUtils.copyProperties(orderDerateVo, orderDerate);
                orderDerate.setOrderId(orderInfo.getId());
                orderDerateMapper.insert(orderDerate);
            });
        }

        // 将新的订单号，设置给orderInfoVo对象
        orderInfoVo.setTradeNo(orderNo);

        // 返回订单号
        return orderNo ;
    }

    @Override
    public String getPayWay() {
        return SystemConstant.ORDER_PAY_WAY_WEIXIN;
    }

    @Override
    public void saveOrderAfterProcess(OrderInfoVo orderInfoVo) {
        this.sendDelayTask(orderInfoVo);   // // 向Redis中发布延迟任务 保存订单数据以后的后续操作
    }

    // 向Redis中发布延迟任务
    public void sendDelayTask(OrderInfoVo orderInfoVo){

        // 向Redis中发布延迟任务
        RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque("order:info:delay:queue");
        RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
        delayedQueue.offer(orderInfoVo.getTradeNo() , RedisConstant.ORDER_INFO_TIME_OUT , TimeUnit.SECONDS);

    }
    }

